package com.xinqi.modules.prepare.common.service.impl;

import com.xinqi.common.base.dto.CommonFileDTO;
import com.xinqi.common.base.dto.QuestionBaseDTO;
import com.xinqi.common.base.dto.QuestionOptionsDTO;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.utils.json.JSON;
import com.xinqi.modules.prepare.common.convert.PrepareImportConvert;
import com.xinqi.modules.prepare.common.dto.data.PrepareCoursewareData;
import com.xinqi.modules.prepare.common.dto.data.PrepareDataData;
import com.xinqi.modules.prepare.common.dto.data.PrepareDiscussData;
import com.xinqi.modules.prepare.common.dto.data.PrepareExamPaperData;
import com.xinqi.modules.prepare.common.dto.data.PrepareHomeworkData;
import com.xinqi.modules.prepare.common.dto.data.PrepareNoticeData;
import com.xinqi.modules.prepare.common.dto.data.PrepareQuestionBankData;
import com.xinqi.modules.prepare.common.dto.data.PrepareVideoData;
import com.xinqi.modules.prepare.common.dto.input.PrepareImportCoursewareData;
import com.xinqi.modules.prepare.common.dto.input.PrepareImportCreateDTO;
import com.xinqi.modules.prepare.common.dto.input.PrepareImportExamPaperData;
import com.xinqi.modules.prepare.common.dto.input.PrepareImportVideoData;
import com.xinqi.modules.prepare.common.mapper.PrepareImportMapper;
import com.xinqi.modules.prepare.common.service.PrepareAuthService;
import com.xinqi.modules.prepare.common.service.PrepareImportService;
import com.xinqi.modules.prepare.courseware.service.PrepareCoursewareService;
import com.xinqi.modules.prepare.data.service.PrepareDataService;
import com.xinqi.modules.prepare.discuss.service.PrepareDiscussService;
import com.xinqi.modules.prepare.homework.service.PrepareHomeworkService;
import com.xinqi.modules.prepare.notice.service.PrepareNoticeService;
import com.xinqi.modules.prepare.paper.service.PrepareExamPaperService;
import com.xinqi.modules.prepare.prepare.enums.PrepareMemberPermissionEnum;
import com.xinqi.modules.prepare.prepare.enums.PrepareTypeEnum;
import com.xinqi.modules.prepare.question.dto.QuestionImportDTO;
import com.xinqi.modules.prepare.question.service.PrepareQuestionBankService;
import com.xinqi.modules.prepare.video.service.PrepareVideoService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

;


/**
 * @author linkai
 * @date 2023/4/12
 */
@Service("prepareImportServiceImpl")
@RequiredArgsConstructor
public class PrepareImportServiceImpl implements PrepareImportService {
    private final PrepareCoursewareService prepareCoursewareService;
    private final PrepareVideoService prepareVideoService;
    private final PrepareDataService prepareDataService;
    private final PrepareHomeworkService homeworkService;
    private final PrepareExamPaperService prepareExamPaperService;
    private final PrepareDiscussService prepareDiscussService;
    private final PrepareNoticeService prepareNoticeService;
    private final PrepareQuestionBankService prepareQuestionBankService;
    private final PrepareAuthService prepareAuthService;
    private final PrepareImportMapper prepareImportMapper;
    private final PrepareImportConvert prepareImportConvert;

    /**
     * 导入互动课件
     */
    @Override
    public Long importCourseware(PrepareCoursewareData data) {
        return prepareCoursewareService.insert(data);
    }

    /**
     * 导入互动课件、保存切片、保存题目.这里使用的模型是备课区的模型，实际数据来源于课程区互动课件
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long cascadeImportCourseware(@Valid PrepareImportCreateDTO dto) {
        prepareAuthService.check(dto.getTargetPrepareId(), PrepareMemberPermissionEnum.新建);

        //课程互动课件
        PrepareImportCoursewareData coursewareData = prepareImportMapper.findCoursewareDataByIdAndType(dto.getSourceId(), Integer.parseInt(PrepareTypeEnum.INTERACT_COURSEWARE.getCode()));
        CommonErrors.NOT_FOUND.check(Objects.nonNull(coursewareData), "互动课件不存在");

        PrepareCoursewareData prepareCoursewareData = prepareImportConvert.convertCourseware(coursewareData);
        prepareCoursewareData.setPrepareId(dto.getTargetPrepareId());
        prepareCoursewareData.setFolderId(dto.getTargetPid());
        // 设置 互动课件文件
        prepareCoursewareData.setFiles(JSON.parseList(coursewareData.getFileUrls(), CommonFileDTO.class));
        if (CollectionUtils.isNotEmpty(prepareCoursewareData.getFiles())) {
            prepareCoursewareData.getFiles().forEach(v -> v.setUrl(v.getFileUrl()));
        }
        //课程互动课件切片
        List<PrepareImportCoursewareData.PrepareImportCoursewarePartData> resourcePartList = prepareImportMapper.findCoursePartListByContentId(coursewareData.getId());
        if (CollectionUtils.isNotEmpty(resourcePartList)) {
            this.setCoursewarePartList(resourcePartList, prepareCoursewareData);
        }

        return importCourseware(prepareCoursewareData);
    }


    /**
     * 设置互动课件上的切片，包含dto转换
     */
    private void setCoursewarePartList(List<PrepareImportCoursewareData.PrepareImportCoursewarePartData> sourcePartList, PrepareCoursewareData targetPartData) {
        List<PrepareCoursewareData.PrepareCoursewarePartData> prepareCoursewarePartDataList = new ArrayList<>();

        for (PrepareImportCoursewareData.PrepareImportCoursewarePartData partData : sourcePartList) {
            partData.setName("第" + (partData.getPageNumber() + 1) + "个切片");
            partData.setPageNumber(partData.getPageNumber() + 1);

            //dto转换
            PrepareCoursewareData.PrepareCoursewarePartData prepareCoursewarePartData = prepareImportConvert.convertCoursewarePart(partData);

            CommonFileDTO file = new CommonFileDTO();
            file.setOssFilename(partData.getName());
            file.setFilename(partData.getName());
            file.setType(Integer.valueOf(partData.getFileType()));
            file.setUrl(partData.getFileUrl());
            file.setFileUrl(partData.getFileUrl());
            prepareCoursewarePartData.setFile(file);

            this.setCoursewareQuestionList(partData, sourcePartList, prepareCoursewarePartData);
            prepareCoursewarePartDataList.add(prepareCoursewarePartData);
        }
        targetPartData.setPartList(prepareCoursewarePartDataList);
    }

    /**
     * 设置互动课件上的试题
     */
    private void setCoursewareQuestionList(PrepareImportCoursewareData.PrepareImportCoursewarePartData sourcePartData,
                                           List<PrepareImportCoursewareData.PrepareImportCoursewarePartData> sourcePartList, PrepareCoursewareData.PrepareCoursewarePartData targetPartData) {
        List<Long> resourcePartIds = sourcePartList.stream().map(PrepareImportCoursewareData.PrepareImportCoursewarePartData::getId).collect(Collectors.toList());
        List<QuestionImportDTO> questionList = this.getQuestionLibraryList(sourcePartData.getCoursewareId(), resourcePartIds);

        if (CollectionUtils.isNotEmpty(questionList)) {
            List<QuestionBaseDTO> questionBaseList = this.getQuestionList(sourcePartData.getId(), questionList);
            targetPartData.setQuestionContent(questionBaseList);
        }
    }

    /**
     * 导入互动视频
     */
    @Override
    public Long importVideo(PrepareVideoData data) {
        return prepareVideoService.insert(data);
    }

    /**
     * 导入互动视频,视频帧可以关联文件、图片和文档
     */
    @Override
    public Long cascadeImportVideo(@Valid PrepareImportCreateDTO dto) {
        prepareAuthService.check(dto.getTargetPrepareId(), PrepareMemberPermissionEnum.新建);

        //课程互动视频
        PrepareImportVideoData videoData = prepareImportMapper.findVideoDataByIdAndType(dto.getSourceId(), Integer.parseInt(PrepareTypeEnum.INTERACT_VIDEO.getCode()));
        CommonErrors.NOT_FOUND.check(Objects.nonNull(videoData), "互动视频不存在");

        PrepareVideoData prepareVideoData = prepareImportConvert.convertVideo(videoData);
        prepareVideoData.setPrepareId(dto.getTargetPrepareId());
        prepareVideoData.setFolderId(dto.getTargetPid());

        //课程互动视频帧
        List<PrepareImportVideoData.PrepareImportVideoPointData> videoPointList = prepareImportMapper.findVideoPointListByContentId(videoData.getId());
        if (CollectionUtils.isNotEmpty(videoPointList)) {
            this.setVideoPointList(videoPointList, prepareVideoData);
        }

        return importVideo(prepareVideoData);
    }

    private void setVideoPointList(List<PrepareImportVideoData.PrepareImportVideoPointData> sourceVideoPointList, PrepareVideoData targetVideoData) {
        List<PrepareVideoData.PrepareVideoPointData> prepareVideoPointDataList = new ArrayList<>();

        for (PrepareImportVideoData.PrepareImportVideoPointData pointData : sourceVideoPointList) {
            pointData.setName("第" + (pointData.getPointNumber()) + "个视频帧");

            PrepareVideoData.PrepareVideoPointData prepareVideoPointData = prepareImportConvert.convertVideoPointPart(pointData);
            List<CommonFileDTO> files = new ArrayList<>();
            CommonFileDTO file = new CommonFileDTO();
            file.setOssFilename(pointData.getName());
            file.setFilename(pointData.getName());
            file.setUrl(pointData.getFileUrl());
            file.setFileUrl(pointData.getFileUrl());
            files.add(file);

            prepareVideoPointData.setFiles(files);
            this.setVideoPointQuestionList(pointData, sourceVideoPointList, prepareVideoPointData);
            prepareVideoPointDataList.add(prepareVideoPointData);
        }

        targetVideoData.setPointList(prepareVideoPointDataList);
    }

    private void setVideoPointQuestionList(PrepareImportVideoData.PrepareImportVideoPointData sourcePointData,
                                           List<PrepareImportVideoData.PrepareImportVideoPointData> videoPointList, PrepareVideoData.PrepareVideoPointData targetPointData) {
        if (CollectionUtils.isNotEmpty(sourcePointData.getQuestions())) {
            targetPointData.setQuestionContent(sourcePointData.getQuestions());
        } else {
            List<Long> videoPointIds = videoPointList.stream().map(PrepareImportVideoData.PrepareImportVideoPointData::getId).collect(Collectors.toList());
            List<QuestionImportDTO> questionList = this.getQuestionLibraryList(sourcePointData.getVideoId(), videoPointIds);

            if (CollectionUtils.isNotEmpty(questionList)) {
                List<QuestionBaseDTO> questionBaseList = this.getQuestionList(sourcePointData.getId(), questionList);
                targetPointData.setQuestionContent(questionBaseList);
            }
        }
    }

    private List<QuestionBaseDTO> getQuestionList(Long sourceId, List<QuestionImportDTO> questionList) {
        List<QuestionBaseDTO> questionBaseList = new ArrayList<>();

        for (QuestionImportDTO question : questionList) {
            if (Objects.equals(question.getResourcePartId(), sourceId)) {
                QuestionBaseDTO questionBase = prepareImportConvert.convertQuestion(question);
                questionBaseList.add(questionBase);
            }
        }
        return questionBaseList;
    }

    @Override
    public Long importStudyData(PrepareDataData data) {
        return prepareDataService.insert(data);
    }

    @Override
    public Long importHomework(PrepareHomeworkData data) {
        return homeworkService.insert(data);
    }

    /**
     * 导入测评
     */
    @Override
    public Long importExamPaper(PrepareExamPaperData data) {
        return prepareExamPaperService.insert(data);
    }

    /**
     * 导入测评
     */
    @Override
    public Long cascadeImportExamPaper(@Valid PrepareImportCreateDTO dto) {
        prepareAuthService.check(dto.getTargetPrepareId(), PrepareMemberPermissionEnum.新建);

        PrepareImportExamPaperData examPaperData = prepareImportMapper.findExamPaperDataById(dto.getSourceId());
        CommonErrors.NOT_FOUND.check(Objects.nonNull(examPaperData), "测评卷不存在");

        PrepareExamPaperData prepareExamPaperData = prepareImportConvert.convertExam(examPaperData);
        prepareExamPaperData.setPrepareId(dto.getTargetPrepareId());
        prepareExamPaperData.setFolderId(dto.getTargetPid());
        return importExamPaper(prepareExamPaperData);
    }

    private List<QuestionImportDTO> getQuestionLibraryList(Long contentId, List<Long> resourcePartIds) {
        //切片上的试题
        List<QuestionImportDTO> questionLibraryList = prepareImportMapper.findQuestionLibListByContentIdAndSourceIds(contentId, resourcePartIds);
        // 初始化 json格式数据
        initQuestJsonParam(questionLibraryList);
        return questionLibraryList;

    }

    /**
     * 初始化 json格式数据
     */
    private static void initQuestJsonParam(List<QuestionImportDTO> questionLibraryList) {
        // 初始化 json格式数据
        questionLibraryList.forEach(v -> {
            if (v.getOptions() != null) {
                v.setOptionList(JSON.parseList(v.getOptions(), QuestionOptionsDTO.class));
            }
            if (v.getQuestionFile() != null) {
                v.setQuestionFiles(JSON.parseList(v.getQuestionFile(), CommonFileDTO.class));
            }
            if (v.getAnswerFile() != null) {
                v.setAnswerFiles(JSON.parseList(v.getAnswerFile(), CommonFileDTO.class));
            }
            if (v.getAnalysisFile() != null) {
                v.setAnalysisFiles(JSON.parseList(v.getAnalysisFile(), CommonFileDTO.class));
            }
        });
    }

    @Override
    public Long importDiscuss(PrepareDiscussData data) {
        return prepareDiscussService.insert(data);
    }

    @Override
    public Long importNotice(PrepareNoticeData data) {
        return prepareNoticeService.insert(data);
    }

    @Override
    public Long importQuestion(PrepareQuestionBankData data) {
        return prepareQuestionBankService.insert(data);
    }

}
